package twitter;

import java.util.AbstractQueue;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Queue;
import java.util.Set;

public class HierarchicalClustering extends Clusterizador{
	
	private int numcluster = 2;
	private ArrayList<TwittProcesado> listaTweets;
	
	private Queue<Dendrogram> cjtoDendogram;
	
	public HierarchicalClustering(int numeroClusters, ArrayList<TwittProcesado> todosTweets) {
		numcluster = numeroClusters;
		listaTweets = todosTweets;	
	}
	
	public void ejecutar(){
		
		cjtoDendogram = new ColaDendrograms();
		for (int i=0; i<listaTweets.size(); i++){
			cjtoDendogram.add(listaTweets.get(i));
		}
		
		while (cjtoDendogram.size()>numcluster){
			Queue<Dendrogram> cjtoDendogramAux = new ColaDendrograms();
			for (Dendrogram cluster : cjtoDendogram){
				for (Dendrogram cluster2 : cjtoDendogram){
					double[] centroideDistancia;
					if (cluster2 instanceof TwittProcesado)
						centroideDistancia = ((TwittProcesado)cluster2).getVectorIdf();
					else
						centroideDistancia = cluster2.getCentroide();
					double distancia = calcularDistancia(cluster, centroideDistancia);
					if (cluster.getDistanciaAlCentroide()>distancia && cluster!=cluster2){
						cluster.setDistanciaAlCentroide(distancia);
						cluster.setCercano(cluster2);
						
					}
					
				}
			}
			
			while (cjtoDendogram.size()>0){
				Dendrogram cluster = cjtoDendogram.element();
				if(cluster.getCercano() == null)
					System.out.println("Este hijo puta falla");
				if (cluster.getCercano().getCercano()==cluster){
					ArrayList<double[]> puntos = new ArrayList<double[]>();
					if (cluster instanceof TwittProcesado)
						puntos.add(((TwittProcesado)cluster).getVectorIdf());
					else
						puntos.add(cluster.getCentroide());
					
					if (cluster.getCercano() instanceof TwittProcesado)
						puntos.add(((TwittProcesado)cluster.getCercano()).getVectorIdf());
					else
						puntos.add(cluster.getCercano().getCentroide());
					
					Dendrogram nuevocluster = new Dendrogram(cluster, cluster.getCercano(), calcularCentroide(puntos));
					cjtoDendogramAux.add(nuevocluster);
					cjtoDendogram.remove(cluster); cjtoDendogram.remove(cluster.getCercano());
					//cjtoUsados.add(cluster);cjtoUsados.add(cluster.getCercano());
				}
				else {
					cluster.setDistanciaAlCentroide(Double.MAX_VALUE);
					cjtoDendogramAux.add(cluster);
					cjtoDendogram.remove(cluster);
				}
				
			}
			cjtoDendogram = cjtoDendogramAux;
		}
		imprimirClusters();
	}
	
	private void imprimirClusters(){
		int i=1;
		cjtoFinalClusters = new HashSet<Set<String>>();
		for (Dendrogram cluster : cjtoDendogram) {
			
			Set<String> cjtoTwitts = new HashSet<String>();
			System.out.println("//------------ Cluster numero " + i + " ------------//");
			recorreArbol(cluster, cjtoTwitts);
			cjtoFinalClusters.add(cjtoTwitts);
			i++;
		}
	}

	private void recorreArbol(Dendrogram cluster, Set<String> cjtoTwitts) {
		
		if (cluster instanceof TwittProcesado){
			String tweet = ((TwittProcesado) cluster).getTweet(); 
			System.out.println(tweet);
			cjtoTwitts.add(tweet);
		}
		else {
			Dendrogram hijoIzq=cluster.getHijoIzq();
			Dendrogram hijoDer=cluster.getHijoDer();
			if (hijoIzq!=null)
				recorreArbol(hijoIzq, cjtoTwitts);
			if (hijoDer!=null)
				recorreArbol(hijoDer, cjtoTwitts);
		}
			
	} 
	
	private class ColaDendrograms extends AbstractQueue<Dendrogram>{
		
		private ArrayList<Dendrogram> conjunto;
		
		public ColaDendrograms(){
			super();
			conjunto = new ArrayList<Dendrogram>();
		}

		@Override
		public Iterator<Dendrogram> iterator() {
			return conjunto.iterator();
		}

		@Override
		public int size() {
			return conjunto.size();
		}

		@Override
		public boolean offer(Dendrogram e) {
			return conjunto.add(e);
		}

		@Override
		public Dendrogram peek() {
			if (conjunto.size()==0)
				return null;
			return conjunto.get(0);
		}

		@Override
		public Dendrogram poll() {
			if (conjunto.size()==0)
				return null;
			Dendrogram primero = conjunto.get(0);
			conjunto.remove(0);
			return primero;
		}
		
	}
	
}
